/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Client.gui;

import Client.domain.ClientDomainController;
import Client.domain.ClientGameSession;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

/**
 *
 * @author Ripper
 */
public class ClientWindow extends JFrame implements KeyListener
{
    private ClientDomainController cdc;
    
    private JPanel activePanelHolder;
    private ClientPanel activePanel;
    
    private LoginPanel loginScreen;
    private RegisterPanel registerScreen;
    private WelcomePanel welcomeScreen;
    private LevelUpAttributePanel levelupattributescreen;
    private EditPlayerPanel editplayerscreen;
    private ViewLobbyPanel viewlobbyscreen;
    private GameLobbyPanel gamelobbyscreen;
    private GamePanel gamescreen;
    private PlayerInventoryPanel playerInventoryScreen;
    //TODO: add more attributes for panels
    
    public ClientWindow()
    {
        super("Project DM - client");
        setLayout(new BorderLayout());
        setSize(800,600);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        cdc = new ClientDomainController(this);
        
        activePanelHolder = new JPanel(new BorderLayout());
        activePanelHolder.addKeyListener(this);
        add(activePanelHolder, BorderLayout.CENTER);
        
        loginScreen = new LoginPanel(this);
        registerScreen = new RegisterPanel(this);
        welcomeScreen = new WelcomePanel(this);
        levelupattributescreen = new LevelUpAttributePanel(this);
        editplayerscreen = new EditPlayerPanel(this);
        viewlobbyscreen = new ViewLobbyPanel(this);
        gamelobbyscreen = new GameLobbyPanel(this);
        gamescreen = new GamePanel(this);
        playerInventoryScreen = new PlayerInventoryPanel(this);
        //TODO: add more creations for panels
        selectActivePanel(loginScreen);
        
        Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
        setLocation((dim.width/2)-getWidth()/2, (dim.height/2)-getHeight()/2);
        
        activePanelHolder.addMouseListener(gamescreen);
        addKeyListener(this);
        setVisible(true);
    }
    
    public void displayErrorMessage(String error)
    {
        JOptionPane.showMessageDialog(null, "ERROR: \n\n"+ error);
    }
    public void displayInfoMessage(String info)
    {
        JOptionPane.showMessageDialog(null, info);
    }
    public void setDungeonMaster(boolean val)
    {
        gamescreen.setDM(val);
    }
    
    private void selectActivePanel(ClientPanel panel)
    {
        activePanel = panel;
        activePanelHolder.removeAll();
        
        activePanelHolder.add(activePanel, BorderLayout.CENTER);
        validate();
        repaint();
    }
    public boolean readyup()
    {
        String response = cdc.askTheServer("readyup");
        if(response.equals("done;"))
        {
            return true;
        }
        return false;
    }
    public boolean cancelreadyup()
    {
        String response = cdc.askTheServer("cancelreadyup");
        if(response.equals("done;"))
        {
            return true;
        }
        return false;
    }
    public void gotoRegistrationScreen()
    {
        selectActivePanel(registerScreen);
    }
    public void gotoLoginScreen()
    {
        selectActivePanel(loginScreen);
    }
    public void selectNextPlayer()
    {
        String resp = cdc.askTheServer("select_next_player");
        
        if(resp.equals("done;"))
        {
            fillWelcomeScreenWithData();
        }
        else
        {
            displayErrorMessage("unable to select next player");
        }
    }
    public void selectPreviousPlayer()
    {
        String resp = cdc.askTheServer("select_prev_player");
        
        if(resp.equals("done;"))
        {
            fillWelcomeScreenWithData();
        }
        else
        {
            displayErrorMessage("unable to select previous player");
        }
    }
    public ClientDomainController getClientDomainController()
    {
        return cdc;
    }
    public void fillWelcomeScreenWithData()
    {
        String response = cdc.askTheServer("user_gold?;actvplr_name?;actvplr_xp2lvl?;"+
                "actvplr_looktype?;actvplr_colors?;"+
                "actvplr_lvl?;actvplr_physdmg?;"+
                "activeplr_magdmg?;activeplr_physarm?;activeplr_magarm?;activeplr_aggrompr?;activeplr_maxhp?;activeplr_maxmana?;"+
                "activeplr_maxstam?;activeplr_hpreg?;activeplr_mpreg?;activeplr_spreg?;activeplr_critchance?;activeplr_critdmgmpr?;"+
                "activeplr_atkspd?;activeplr_movspd?;activeplr_prctspvp?;activeplr_prctlifesteal?");
        String[] data = response.split(";");
        
        String gp = data[0];
        int gold = Integer.parseInt(gp);
        
        if(data.length < 2)
        {
            welcomeScreen.fillWithData(gold);
        }
        else
        {
            String activePlayerName = data[1];
            String xp2lvl = data[2];
            int prctExpToLvl = Integer.parseInt(xp2lvl);
            
            int lookType = Integer.parseInt(data[3]);
            String colorData = data[4];
            Color[] colors = new Color[4];
            {
                //set data
                String[] singleColor = colorData.split("-");
                
                for(int a = 0; a < singleColor.length; a++)
                {
                    String tehColor = singleColor[a];
                    
                    String[] tehColorData = tehColor.split(",");
                    int r = Integer.parseInt(tehColorData[0]);
                    int g = Integer.parseInt(tehColorData[1]);
                    int b = Integer.parseInt(tehColorData[2]);
                    
                    colors[a] = new Color(r,g,b);
                }
            }
            
            int extra = 5;
            String[] statInfo = new String[18];
            for(int a = extra; a < extra+18; a++)
            {
                statInfo[a - extra] = data[a];
            }
            
            welcomeScreen.fillWithData(gold, activePlayerName, statInfo, prctExpToLvl, lookType, colors);
        }
    }
    public void changeColors(Color[] colorings)
    {
        String colors = "";

        for(Color c: colorings)
        {
            colors += c.getRed() + "," + c.getGreen() + "," + c.getBlue() + "-";
        }
        colors = colors.substring(0, colors.length()-1);
        
        String response = cdc.askTheServer("actvplr_changecolors:"+colors);
        
        if(!response.equals("done;"))
        {
            displayErrorMessage("Unable to save colors.");
        }
    }
    public void gotoWelcomeScreen()
    {
        fillWelcomeScreenWithData();
        selectActivePanel(welcomeScreen);
    }
    public void fillLevelUpAttributePanel()
    {
        String response = cdc.askTheServer("actvplr_name?;actvplr_lvl?;actvplr_xp2lvl?;actvplr_attributepointsavailable?;actvplr_attributeinfo?");
        String[] data = response.split(";");
        
        String playerName = data[0];
        int level = Integer.parseInt(data[1]);
        int xpPrct = Integer.parseInt(data[2]);
        
        int attributepointsavailable = Integer.parseInt(data[3]);
        
        String attributeInfo = data[4];
        String[] dat = attributeInfo.split("-");
        
        levelupattributescreen.fillWithData(playerName, level, xpPrct, attributepointsavailable, dat);
    }
    public void fillEditPlayerPanel()
    {
        String response = cdc.askTheServer("actvplr_looktype?;actvplr_colors?");
        String[] bits = response.split(";");
        
        int looktype = Integer.parseInt(bits[0]);
        String colorData = bits[1];
        Color[] colors = new Color[4];
        {
            //set data
            String[] singleColor = colorData.split("-");

            for(int a = 0; a < singleColor.length; a++)
            {
                String tehColor = singleColor[a];

                String[] tehColorData = tehColor.split(",");
                int r = Integer.parseInt(tehColorData[0]);
                int g = Integer.parseInt(tehColorData[1]);
                int b = Integer.parseInt(tehColorData[2]);

                colors[a] = new Color(r,g,b);
            }
        }
        
        editplayerscreen.fillWithData(looktype, colors);
    }
    public void levelupAttributePoint(int index)
    {
        String response = cdc.askTheServer("actvplr_levelup_attribute:"+index);
        
        if(response.equals("done;"))
        {
            fillLevelUpAttributePanel();
        }
        else if(response.equals("insufficient;"))
        {
            displayErrorMessage("Insufficient attribute points available!");
        }
        else
        {
            displayErrorMessage("unable to apply levelup point");
        }
    }
    public void createNewPlayer(String newPlrNm)
    {
        if(newPlrNm != null && newPlrNm.length() > 0)
        {
            newPlrNm = newPlrNm.replace(',', '_');
            newPlrNm = newPlrNm.replace(':', '_');
            newPlrNm = newPlrNm.replace(';', '_');
            newPlrNm = newPlrNm.replace('|', '_');
            newPlrNm = newPlrNm.replace('(', '_');
            newPlrNm = newPlrNm.replace(')', '_');
            newPlrNm = newPlrNm.replace('.', '_');

            String response = cdc.askTheServer("create_new_player:"+newPlrNm);

            if(response.equals("done;"))
            {
                fillWelcomeScreenWithData();
            }
            else
            {
                displayErrorMessage("unable to create new player.");
            }
        }
    }
    public void createNewSession(String sessionName)
    {
        sessionName = sessionName.replace(',', '_');
        sessionName = sessionName.replace(':', '_');
        sessionName = sessionName.replace(';', '_');
        sessionName = sessionName.replace('|', '_');
        sessionName = sessionName.replace('(', '_');
        sessionName = sessionName.replace(')', '_');
        sessionName = sessionName.replace('.', '_');
        
        String response = cdc.askTheServer("createsession:"+sessionName);
        
        if(response.equals("done;"))
        {
            connectToSession(sessionName);
        }
        else
        {
            displayErrorMessage("Unable to create new session (session name is taken?).");
        }
    }
    public void connectToSession(String sessionName)
    {
        String data = cdc.askTheServer("connectto:"+sessionName);
        
        if(data.equals("done;"))
        {
            gotoGameLobbyPanel(sessionName);
        }
        else
        {
            displayErrorMessage("Unable to connect to session: "+sessionName);
        }
    }
    public void disconnectFromSession()
    {
        String response = cdc.askTheServer("disconnectfrom");
        if(response.equals("done;"))
        {
            cdc.shutdowngame();
            viewLobbies();
        }
        else
        {
            displayErrorMessage("Unable to disconnect from session");
        }
    }
    public void gotoGameLobbyPanel(String sessionName)
    {
        gamelobbyscreen.startViewingData(sessionName);
        selectActivePanel(gamelobbyscreen);
    }
    public void viewAttributePoints()
    {
        try
        {
            fillLevelUpAttributePanel();
            selectActivePanel(levelupattributescreen);
        }
        catch(Exception ex)
        {
            displayErrorMessage("No active player selected.");
        }
    }
    public void editPlayer()
    {
        try
        {
            fillEditPlayerPanel();
            selectActivePanel(editplayerscreen);
        }
        catch(Exception ex) 
        {
            displayErrorMessage("No active player selected.");
        }
    }
    public void loginOk(String userName)
    {   
        welcomeScreen.setUserName(userName);

        fillWelcomeScreenWithData();
        
        selectActivePanel(welcomeScreen);
    }
    public void attemptLogin(String username, String password)
    {
        try
        {
            cdc.login(username, password);
        }
        catch(Exception ex)
        {
            displayErrorMessage("Connection problem: "+ex.getMessage());
        }
    }
    public void attemptRegistration(String[] data)
    {
        try
        {
            cdc.register(data);
        }
        catch(Exception ex)
        {
            displayErrorMessage("Connection problem: "+ex.getMessage());
        }
    }

    public void setNewLooktype(int looktype) 
    {
        String response = cdc.askTheServer("actvplr_setnewlooktype:"+looktype);
        
        if(!response.equals("done;"))
        {
            displayErrorMessage("Unable to set new looktype.");
        }
    }
    public void viewLobbies()
    {
        try
        {
            fillLobbyPanel();
            selectActivePanel(viewlobbyscreen);
        }
        catch(Exception ex)
        {
            
        }
    }
    public boolean becomeorresignasDM(boolean isDM)
    {
        try
        {
            if(isDM)
            {
                String resp = cdc.askTheServer("resignasDM");
                
                if(resp.equals("done;"))
                {
                    return true;
                }
                return false;
            }
            else
            {
                String resp = cdc.askTheServer("becomeDM");
                
                if(resp.equals("done;"))
                {
                    return true;
                }
                return false;
            }
        }
        catch(Exception ex)
        {
            
        }
        return false;
    }
    public void fillLobbyPanel()
    {
        String response = cdc.askTheServer("getactivesessions;getinactivesessions");
        
        String[] bits = response.split(";");
        
        String activeBit = null;
        String inactiveBit = null;
        
        try
        {
            activeBit = bits[0];
        }catch(Exception ex) 
        {
            activeBit = "";
        }
        try
        {
            inactiveBit = bits[1];
        }catch(Exception ex) 
        {
            inactiveBit = "";
        }
        
        String[] activeSessions = null;
        try
        {
            activeSessions = activeBit.split("-");
            
            if(activeSessions.length == 1 && activeSessions[0].equals(""))
            {
                activeSessions = null;
            }
        }catch(Exception ex) {
            activeSessions = null;
        }
        String[] inactiveSessions = null;
        try
        {
            inactiveSessions = inactiveBit.split("-");
            
            //if(inactiveSessions.length < 1)
            if(inactiveSessions.length == 1 && inactiveSessions[0].equals(""))
            {
                inactiveSessions = null;
            }
        }catch(Exception ex){
            inactiveSessions = null;
        }
        
        viewlobbyscreen.fillWithData(activeSessions, inactiveSessions);
    }
    
    public void startTheGame() throws Exception
    {
        String response = cdc.askTheServer("startsession");
        
        if(!response.equals("done;"))
        {
            throw new Exception("");
        }
    }
    public void gotoGameScreen()
    {
        selectActivePanel(gamescreen);
        activePanelHolder.requestFocus();
    }
    public void playerHasSpoken(String plr, String encodedMsg)
    {
        gamescreen.playerHasSpoken(plr,encodedMsg);
    }
    public void addTextEffect(Color c, int x, int y, String txt)
    {
        gamescreen.addTextEffect(c,x,y,txt);
    }
    
    public void updateGameScreen(ClientGameSession cgs)
    {
        gamescreen.updateGame(cgs);
    }

    @Override
    public void keyTyped(KeyEvent e) 
    {
        gamescreen.keyTyped(e);
    }

    @Override
    public void keyPressed(KeyEvent e) 
    {
        gamescreen.keyPressed(e);
    }

    @Override
    public void keyReleased(KeyEvent e) 
    {
        gamescreen.keyReleased(e);
        
    }

    public void viewInventory() 
    {
        try
        {
            updatePlayerInventoryScreen();
            selectActivePanel(playerInventoryScreen);
        }
        catch(Exception ex)
        {
            displayErrorMessage("No active player selected.");
        }
    }
    public void updatePlayerInventoryScreen()
    {
        playerInventoryScreen.refreshData();
    }
}